from typing import List, Optional
from sqlalchemy.orm import Session
from sqlalchemy import and_
from ..models.models import Admin, Building, Room, Student, SwapRequest
from datetime import datetime

class AdminService:
    @staticmethod
    def get_admin_buildings(db: Session, admin_id: int) -> List[Building]:
        """获取管理员负责的楼栋"""
        admin = db.query(Admin).filter(Admin.admin_id == admin_id).first()
        if not admin:
            return []
        return [ab.building for ab in admin.admin_buildings]

    @staticmethod
    def get_building_rooms(db: Session, building_id: int) -> List[Room]:
        """获取楼栋的所有房间"""
        return db.query(Room).filter(Room.building_id == building_id).all()

    @staticmethod
    def get_room_occupancy(db: Session, room_id: int) -> dict:
        """获取房间入住情况"""
        room = db.query(Room).filter(Room.id == room_id).first()
        if not room:
            return None
        
        return {
            "room_id": room.id,
            "room_number": room.room_number,
            "capacity": room.capacity,
            "current_occupancy": room.current_occupancy,
            "students": [
                {
                    "student_id": student.student_id,
                    "name": student.name,
                    "gender": student.gender.value
                }
                for student in [assignment.student for assignment in room.assignments if assignment.is_active]
            ]
        }

    @staticmethod
    def process_swap_request(
        db: Session,
        request_id: int,
        admin_id: int,
        approve: bool
    ) -> bool:
        """处理调换申请"""
        request = db.query(SwapRequest).filter(
            SwapRequest.id == request_id
        ).first()
        
        if not request or request.status != 'pending':
            return False

        try:
            if approve:
                # 获取申请者和目标学生的当前房间分配
                requester_assignment = request.requester.room_assignment
                target_assignment = request.target.room_assignment
                
                if not requester_assignment or not target_assignment:
                    return False
                
                # 交换房间分配
                requester_room = requester_assignment.room
                target_room = target_assignment.room
                
                requester_assignment.room = target_room
                target_assignment.room = requester_room
                
                request.status = 'approved'
            else:
                request.status = 'rejected'
            
            request.processed_by = admin_id
            request.updated_at = datetime.utcnow()
            
            db.commit()
            return True
        except Exception as e:
            db.rollback()
            return False

    @staticmethod
    def get_building_statistics(db: Session, building_id: int) -> dict:
        """获取楼栋统计信息"""
        building = db.query(Building).filter(Building.id == building_id).first()
        if not building:
            return None
            
        rooms = building.rooms
        total_rooms = len(rooms)
        total_capacity = sum(room.capacity for room in rooms)
        total_occupied = sum(room.current_occupancy for room in rooms)
        
        return {
            "total_rooms": total_rooms,
            "total_capacity": total_capacity,
            "total_occupied": total_occupied,
            "occupancy_rate": round(total_occupied / total_capacity * 100, 2) if total_capacity > 0 else 0,
            "available_beds": total_capacity - total_occupied
        }

    @staticmethod
    def get_pending_requests(db: Session, admin_id: int) -> List[SwapRequest]:
        """获取待处理的调换申请"""
        admin = db.query(Admin).filter(Admin.admin_id == admin_id).first()
        if not admin:
            return []
        
        # 获取管理员负责的楼栋ID列表
        building_ids = [ab.building_id for ab in admin.admin_buildings]
        
        # 查找这些楼栋中的待处理申请
        pending_requests = (
            db.query(SwapRequest)
            .join(Student, SwapRequest.requester_id == Student.id)
            .join(RoomAssignment, Student.room_assignment)
            .join(Room, RoomAssignment.room_id == Room.id)
            .filter(
                and_(
                    Room.building_id.in_(building_ids),
                    SwapRequest.status == 'pending'
                )
            )
            .all()
        )
        
        return pending_requests 